namespace fpsrpg
{
    using System;
    using System.Collections.Generic;
    using System.Text;

    using DynamicShadows;

    using Lidgren.Network;
    using Lidgren.Network.Xna;

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using Microsoft.Xna.Framework.Storage;

    using xWinFormsLib;

    using WinForms = System.Windows.Forms;

    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public partial class Game1 : Microsoft.Xna.Framework.Game
    {
        #region Fields

        /// <summary>
        /// The current local player
        /// </summary>
        public Player Player;
        /// <summary>
        /// The size of the screen that we are rendering to
        /// </summary>
        public int ScreenWidth, ScreenHeight;

        private KeyboardState aCurrentKeyboardState = Keyboard.GetState();
        private MouseState aCurrentMouseState = Mouse.GetState();
        private Texture2D alphaClearTexture;
        private AudioEngine audioEngine;
        private Bullets bullet = new Bullets();
        private Texture2D crosshair;
        private NpcEnemy Enemy;
        private Color[] EnemyTextureData;
        private FormCollection formCollection;
        private GraphicsDeviceManager graphics;
        private float healingdelay = 0.0f;
        private bool InMenu;
        private Label label_customize_body_title;
        private Label label_customize_hat_title;
        private RenderTarget2D lightMap;
        private LightSource[] lights;
        private bool LoadRequested;
        private KeyboardState mPreviousKeyboardState;
        private MouseState mPreviousMouseState;
        private ConvexHull[] objects;
        private int OldScrollWheelValue;
        private Vector2 PlayerPosition_network;
        private Rectangle PlayerRectangle;
        private Color[] PlayerTextureData;
        private LightSource[] rotatedlights;
        private bool SaveRequested;
        private SoundBank soundBank;
        private SpriteBatch spriteBatch;
        private IAsyncResult storage_result;
        private Talents_Medic talents_medic;
        private float time;
        private List<Unit> UnitsInGame = new List<Unit>();
        private SpriteFont UVfont;
        /// <summary>
        /// Main wavebank that is used with the audio engine
        /// </summary>
        private WaveBank waveBank;

        ////const int maxGamers = 16;
        ////const int maxLocalGamers = 4;
        ////NetworkSession networkSession;
        ////PacketWriter packetWriter = new PacketWriter();
        ////PacketReader packetReader = new PacketReader();

        /// <summary>
        /// Networking client
        /// </summary>
        private NetClient _client;
        /// <summary>
        /// Networking Config
        /// </summary>
        private NetConfiguration _nac;
        /// <summary>
        /// Networking server
        /// </summary>
        private NetServer _server;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the Game1 class.
        /// </summary>
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            //Components.Add(new GamerServicesComponent(this));
        }

        #endregion Constructors

        #region Methods

        /// <summary>
        /// Adds a message box to the gui. This can be called without respect for threading
        /// </summary>
        /// <param name="msg">The text to be displayed on the message box</param>
        public void AddMessageBox(string msg)
        {
            new MessageBox(new Vector2(250, 150), "Message", msg, MessageBox.Type.MB_OK);
            FormCollection.IsCursorVisible = true;
        }

        /// <summary>
        /// Invoked when the user clicked the keybinding for starting to act as a client
        /// </summary>
        public void ClientClicked()
        {
            //this code if fairly the same as Server so i wont go into detail
            new MessageBox(new Vector2(250, 100), "Acting as Client", "Acting as Client", MessageBox.Type.MB_OK);

            _nac = new NetConfiguration("XNAtoplands");
            //_log = new NetLog();
            //Set it up so that the Log Igores Nothing
            //_log.IgnoreTypes = NetLogEntryTypes.None;
            //We want to Output to file, this shows how to do so.
            //_log.IsOutputToFileEnabled = true;
            //If we output to a file we need to big a name, this was simple
            //_log.OutputFileName = "Client.html";
            _client = new NetClient(_nac);
            //_client.StatusChanged += new EventHandler<NetStatusEventArgs>(client_StatusChanged);
            //Once ready we set the Client to Connect to the LocalHost, Port 12345,
            //if we wanted an IP we would do
            //client.Connect("192.168.1.1",12345); ect.
            _client.Configuration.ApplicationIdentifier = "XNAtoplands";
            //_client.ServerDiscovered += new EventHandler<NetServerDiscoveredEventArgs>(_client_ServerDiscovered);
            _client.Connect("localhost", 6969);
        }

        /// <summary>
        /// Handles incoming network messages and sets the state of our engine
        /// </summary>
        /// <param name="msg">A buffer containing the data that was sen</param>
        public void HandleNetworkingMessage(NetBuffer msg)
        {
            //We read the Messages
            try
            {
                //currRowNetwork = msg.ReadInt();
                PlayerPosition_network = XnaSerialization.ReadVector2(msg);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Invoked when the user wishes to act as a server
        /// </summary>
        public void HostClicked()
        {
            new MessageBox(new Vector2(250, 100), "Acting as Host", "Acting as host", MessageBox.Type.MB_OK);

            //This sets up the configuration, when your setting the config up for server we pick the application name and the port that the server
            //will bound to when we create it
            _nac = new NetConfiguration("XNAtoplands");
            //set the maximum connects, im not sure the biggest number aloud at this moment in time
            _nac.MaxConnections = 32;
            //This is used for somthing later on in the tutorials, where the client can discover hosts.
            //_nac.ServerName = "Toplands server 1";
            //Initiate the log
            //_log = new NetLog();
            //port
            _nac.Port = 6969;
            //Create the server using the Log and the Configuration, this will bound the port on the computer.
            _server = new NetServer(_nac);
            // Add an Event Handler for when a client connects or disconnects.
            //NetMessageType.StatusChanged += new EventHandler<NEt>(server_StatusChanged);
        }

        //void _client_ServerDiscovered(object sender, NetChannel e)
        //{
        //    if (e.ServerInformation.ServerName == "Toplands server 1")
        //        _client.Connect(e.ServerInformation.RemoteEndpoint.Address, e.ServerInformation.RemoteEndpoint.Port);
        //}
        //void client_StatusChanged(object sender, NetMessageType e)
        //{
        //    //If the client has connected to the server
        //    if (e.Connection.Status == NetConnectionStatus.Connected)
        //    {
        //        new MessageBox(new Vector2(250, 100), "Client connected", "Client connected", MessageBox.Type.MB_OK);
        //    }
        //    //If the Client was disconnected
        //    if (e.Connection.Status == NetConnectionStatus.Disconnected)
        //    {
        //        new MessageBox(new Vector2(250, 100), "Client disconnected", "Client disconnected", MessageBox.Type.MB_OK);
        //    }
        //}
        //void server_StatusChanged(object sender, NetMessageType e)
        //{
        //    if (e.Connection.Status == NetConnectionStatus.Connecting)
        //    {
        //        new MessageBox(new Vector2(250, 100), "Server connected", "Server connected", MessageBox.Type.MB_OK);
        //    }
        //    if (e.Connection.Status == NetConnectionStatus.Disconnected)
        //    {
        //        new MessageBox(new Vector2(250, 100), "Server connected", "Server connected", MessageBox.Type.MB_OK);
        //    }
        //}

        /// <summary>
        /// Called on every update to get data from the network
        /// </summary>
        public void UpdateNetwork()
        {
            NetMessageType type;
            //If the client is chosen this will be called
            if (_client != null)
            {
                NetBuffer buffer = _client.CreateBuffer();
                NetBuffer msgPosition;
                //Message will continue you iterate though any messages received from the Server.
                while (_client.ReadMessage(buffer, out type))
                {
                    //Initialize a new message
                    //We Send the message of to be read and interpreted
                    HandleNetworkingMessage(new NetBuffer());
                }
                    msgPosition = new NetBuffer();
                    //msgPosition.Write("");
                    XnaSerialization.Write(msgPosition, Player.Position);
                    _client.SendMessage(msgPosition, NetChannel.ReliableUnordered);
            }
            //If the Server is chosen this will be called
            if (_server != null)
            {
                //The same as the client....
                NetBuffer msgPosition;

                    //while (_server.ReadMessage(buffer, out type, out _server.Connections))
                    //{
                    //    HandleNetworkingMessage(msgPosition);
                    //}

                msgPosition = new NetBuffer();
                //msg.Write("");
                XnaSerialization.Write(msgPosition, Player.Position);

                foreach (NetConnection conn in _server.Connections)
                {
                    if (conn != null && conn.Status == NetConnectionStatus.Connected)
                        _server.SendMessage(msgPosition, conn, NetChannel.ReliableUnordered);
                }

            }
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            //build lightmap
            DrawLightmap();

            //Render the form collection (required before drawing)
            formCollection.Render();

            GraphicsDevice.Clear(Color.White);

            //draw ground
            DrawGround();


            // TODO: Add your drawing code here
            spriteBatch.Begin();

            //spriteBatch.Draw(Content.Load<Texture2D>("tile_sand"), new Rectangle(0, 0, ScreenWidth, ScreenHeight), Color.White);

            //spriteBatch.Draw(Content.Load<Texture2D>("test_enemy_collision"), bullet.BulletRectangle, Color.White); //Stomme Collision helper voor Bullet :)
            //spriteBatch.Draw(Content.Load<Texture2D>("test_enemy_collision"), EnemyRectangle, Color.White); //Stomme Collision helper voor Enemy :)

            spriteBatch.DrawString(UVfont, Enemy.Health.ToString(), new Vector2(Enemy.Position.X - (Enemy.Size.Width / 2), Enemy.Position.Y - 60), Color.Red);

            //MP player
            //spriteBatch.Draw(mPlayerSprite.mSpriteTexture, new Rectangle((int)PlayerPosition_network.X, (int)PlayerPosition_network.Y, mPlayerSprite.Size.Width, mPlayerSprite.Size.Height), null, Color.White, 0, new Vector2(mPlayerSprite.Size.Width / 2, mPlayerSprite.Size.Height / 2), SpriteEffects.None, 0);

            if (!formCollection["form1"].Visible || formCollection["form1"].State == Form.WindowState.Maximized)
                spriteBatch.Draw(crosshair, new Vector2(aCurrentMouseState.X - (crosshair.Width / 2), aCurrentMouseState.Y - (crosshair.Height / 2)), Color.Red);

            healingdelay += time;
            if (healingdelay > 1.0)
            {
                //Draw the talents
                Enemy.Health += talents_medic.Action_Healing_Circle(Player, this.Content, spriteBatch, EnemyTextureData, Enemy.CollisionBox);
                healingdelay = 0.0f;
            }
            talents_medic.DrawCircle(Player, this.Content, spriteBatch, 3);

            //draw objects
            foreach (ConvexHull hull in objects)
            {
                hull.Draw(gameTime);
            }

            foreach (var unit in UnitsInGame)
            {
                unit.Draw(spriteBatch, Color.White);
            }
            bullet.Draw(spriteBatch);


            spriteBatch.End();

            #region Draw shadows & lighting
            //multiply scene with lightmap
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
            GraphicsDevice.RenderState.SourceBlend = Blend.Zero;
            GraphicsDevice.RenderState.DestinationBlend = Blend.SourceColor;
            GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;
            spriteBatch.Draw(lightMap.GetTexture(), Vector2.Zero, Color.White);
            spriteBatch.End();
            #endregion

            DrawUI(gameTime);
            //Draw the form collection
            formCollection.Draw();

            base.Draw(gameTime);
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            Player = new Player();
            Enemy = new NpcEnemy();

            UnitsInGame.Add(Player);
            UnitsInGame.Add(Enemy);

            talents_medic = new Talents_Medic();

            talents_medic.circle = this.Content.Load<Texture2D>("medic_healing_circle_globe");

            ScreenHeight = graphics.GraphicsDevice.Viewport.Height;
            ScreenWidth = graphics.GraphicsDevice.Viewport.Width;

            Enemy.Position = new Vector2(ScreenWidth / 2, ScreenHeight / 2);
            Enemy.Rotation = 135.0f;

            Player.SwitchWeapon(Properties.Settings.Default.Weapon_equiped);

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            //mPlayerSprite.mContentManager = this.Content;

            #region Load shadow & lighting stuff
            BuildObjectList();

            Texture2D lightTexture = Content.Load<Texture2D>("light");
            Texture2D laserTexture = Content.Load<Texture2D>("laserbeam1");

            lights = new LightSource[1];
            lights[0] = new LightSource(lightTexture, Color.White, 250, Player.Position);
            rotatedlights = new LightSource[1];
            rotatedlights[0] = new LightSource(laserTexture, Color.Red, 3, Player.Position);

            PresentationParameters pp = GraphicsDevice.PresentationParameters;
            lightMap = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight, 1, SurfaceFormat.Color, pp.MultiSampleType, pp.MultiSampleQuality);
            alphaClearTexture = Content.Load<Texture2D>("AlphaOne");
            #endregion

            graphics.PreferredBackBufferHeight = System.Windows.Forms.SystemInformation.PrimaryMonitorSize.Height;
            graphics.PreferredBackBufferWidth = System.Windows.Forms.SystemInformation.PrimaryMonitorSize.Width;
            

            ScreenHeight = graphics.GraphicsDevice.Viewport.Height;
            ScreenWidth = graphics.GraphicsDevice.Viewport.Width;

            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            UVfont = Content.Load<SpriteFont>("TehText");

            // TODO: use this.Content to load your game content here
            Player.LoadContent(this.Content);
            Enemy.LoadContent(this.Content, "test_enemy");

            bullet = new Bullets();

            EnemyTextureData = new Color[Enemy.Size.Width * Enemy.Size.Height];
            Enemy.mSpriteTexture.GetData(EnemyTextureData);

            PlayerTextureData = new Color[Player.Size.Width * Player.Size.Height];
            Player.mSpriteTexture.GetData(PlayerTextureData);

            audioEngine = new AudioEngine("Content/sound/guns.xgs");
            waveBank = new WaveBank(audioEngine, "Content/sound/MyWaveBank.xwb");
            soundBank = new SoundBank(audioEngine, "Content/sound/MySoundBank.xsb");

            crosshair = Content.Load<Texture2D>("crosshair_mediumaccuracy");

            mHealthBar = Content.Load<Texture2D>("HealthBar");

            OldScrollWheelValue = aCurrentMouseState.ScrollWheelValue;

            // Create the formCollection, where all our forms will reside
            formCollection = new FormCollection(this.Window, Services, ref graphics);

            #region Form #1

            //Create a new form
            formCollection.Add(new Form("form1", "Menu", new Vector2(600, 400), new Vector2((ScreenWidth / 2) - 300, (ScreenHeight / 2) - 200), Form.BorderStyle.Fixed));
            //formCollection["form1"].Style = Form.BorderStyle.Sizable;
            //formCollection["form1"].FontName = "pericles9";
            //formCollection["form1"].FontName = "kootenay9";

            //Add a Label
            formCollection["form1"].Controls.Add(new Label("label_mPlayerSprite.hats", new Vector2(0, 30), "Customize your hat:", Color.TransparentWhite, Color.Black, (int)formCollection["form1"].Width, Label.Align.Center));

            //Add a Label
            label_customize_hat_title = new Label("label_customize_hat_title", new Vector2((formCollection["form1"].Width / 2) - 35, 52), Player.hats.Customize_hat_title, Color.TransparentWhite, Color.Black, 70, Label.Align.Center);
            formCollection["form1"].Controls.Add(label_customize_hat_title);

            //Add a Button
            formCollection["form1"].Controls.Add(new Button("button_customize_hat_next", new Vector2((formCollection["form1"].Width / 2) + label_customize_hat_title.Width, 50), 20, ">", Color.White, Color.Black));
            formCollection["form1"]["button_customize_hat_next"].OnPress += Button1_OnPress;

            //Add a Button
            formCollection["form1"].Controls.Add(new Button("button_customize_hat_previous", new Vector2((formCollection["form1"].Width / 2) - label_customize_hat_title.Width, 50), 20, "<", Color.White, Color.Black));
            formCollection["form1"]["button_customize_hat_previous"].OnPress += Button2_OnPress;

            //Add a Label
            formCollection["form1"].Controls.Add(new Label("label_bodies", new Vector2(0, 72), "Customize your body:", Color.TransparentWhite, Color.Black, (int)formCollection["form1"].Width, Label.Align.Center));

            //Add a Label
            label_customize_body_title = new Label("label_customize_body_title", new Vector2((formCollection["form1"].Width / 2) - 35, 92), Player.Customize_body_title, Color.TransparentWhite, Color.Black, 70, Label.Align.Center);
            formCollection["form1"].Controls.Add(label_customize_body_title);

            //Add a Button
            formCollection["form1"].Controls.Add(new Button("button_customize_body_next", new Vector2((formCollection["form1"].Width / 2) + label_customize_body_title.Width, 90), 20, ">", Color.White, Color.Black));
            formCollection["form1"]["button_customize_body_next"].OnPress += Button3_OnPress;

            //Add a Button
            formCollection["form1"].Controls.Add(new Button("button_customize_body_previous", new Vector2((formCollection["form1"].Width / 2) - label_customize_body_title.Width, 90), 20, "<", Color.White, Color.Black));
            formCollection["form1"]["button_customize_body_previous"].OnPress += Button4_OnPress;

            formCollection["form1"].Controls.Add(new Textbox("textbox_name", new Vector2((formCollection["form1"].Width / 2) - 60, 120), 120));
            formCollection["form1"]["textbox_name"].Text = Player.Name;
            formCollection["form1"]["textbox_name"].OnMouseOver += NameChangeTextBox_update;
            //formCollection["form1"].Controls.Add(new Button("btRemove", new Vector2(15, 320), 60, "Remove Listbox Item", Color.White, Color.Black));
            //formCollection["form1"]["btRemove"].OnPress += Remove_OnPress;

            ////Add a Button Row
            //formCollection["form1"].Controls.Add(new ButtonRow("buttonRow1", new Vector2(15, 80), 250, new string[] { "RowButton1", "RowButton2", "RowButton3" }, Color.White, Color.Black));
            //formCollection["form1"]["buttonRow1"].OnRelease = ButtonRow1_OnRelease;

            ////Add a Checkbox
            //formCollection["form1"].Controls.Add(new Checkbox("checkbox1", new Vector2(15, 110), "Checkbox", true));
            //formCollection["form1"]["checkbox1"].OnRelease = Checkbox1_OnRelease;

            ////Add a RadioButton
            //formCollection["form1"].Controls.Add(new RadioButton("radiobutton1", new Vector2(170, 55), "RadioButton", true));
            //formCollection["form1"]["radiobutton1"].OnRelease = Radiobutton1_OnRelease;

            ////Add a Label
            //formCollection["form1"].Controls.Add(new Label("label1", new Vector2(15, 135), "Label #1", Color.White, Color.Black, 70, Label.Align.Left));
            //formCollection["form1"]["label1"].OnMouseOver = Label1_MouseOver;
            //formCollection["form1"]["label1"].OnMouseOut = Label1_MouseOut;
            //formCollection["form1"]["label1"].OnPress = Label1_OnPress;
            //formCollection["form1"]["label1"].OnRelease = Label1_OnRelease;

            //Add a PictureBox
            //formCollection["form1"].Controls.Add(new PictureBox("picturebox_customize_hat" + Properties.Settings.Default.Customize_hat, new Vector2(15, 160), @"content\customize_hat" + Properties.Settings.Default.Customize_hat + ".png", 1));
            //formCollection["form1"]["picturebox1"].OnMouseOver = PictureBox1_MouseOver;
            //formCollection["form1"]["picturebox1"].OnMouseOut = PictureBox1_MouseOut;
            //formCollection["form1"]["picturebox1"].OnPress = PictureBox1_OnPress;
            //formCollection["form1"]["picturebox1"].OnRelease = PictureBox1_OnRelease;

            ////Add a CheckboxGroup
            //formCollection["form1"].Controls.Add(new CheckboxGroup("checkboxgroup1", new Checkbox[] {
            //    new Checkbox("group1check1", new Vector2(165, 130), "Group Check #1", true),
            //    new Checkbox("group1check2", new Vector2(165, 150), "Group Check #2", false),
            //    new Checkbox("group1check3", new Vector2(165, 170), "Group Check #3", false),
            //    new Checkbox("group1check4", new Vector2(165, 190), "Group Check #4", false),
            //    new Checkbox("group1check5", new Vector2(165, 210), "Group Check #5", false)}));
            //((CheckboxGroup)formCollection["form1"]["checkboxgroup1"]).OnChangeSelection = CheckboxGroup1_ChangeSelection;

            ////Add a RadioButtonGroup
            //formCollection["form1"].Controls.Add(new RadioButtonGroup("radiobuttongroup1", new RadioButton[] {
            //    new RadioButton("group1check1", new Vector2(310, 280), "RadioButton #1", true),
            //    new RadioButton("group1check2", new Vector2(310, 300), "RadioButton #2", false),
            //    new RadioButton("group1check3", new Vector2(310, 320), "RadioButton #3", false),
            //    new RadioButton("group1check4", new Vector2(310, 340), "RadioButton #4", false),
            //    new RadioButton("group1check5", new Vector2(310, 360), "RadioButton #5", false)}));
            //((RadioButtonGroup)formCollection["form1"]["radiobuttongroup1"]).OnChangeSelection = RadioButtonGroup1_ChangeSelection;

            ////Add a ButtonGroup
            //formCollection["form1"].Controls.Add(new ButtonGroup("buttongroup1", new Button[] {
            //    new Button("group2button1", new Vector2(165, 250), "Group Button #1", Color.White, Color.Black),
            //    new Button("group2button2", new Vector2(165, 275), "Group Button #2", Color.White, Color.Black),
            //    new Button("group2button3", new Vector2(165, 300), "Group Button #3", Color.White, Color.Black),
            //    new Button("group2button4", new Vector2(165, 325), "Group Button #4", Color.White, Color.Black),
            //    new Button("group2button5", new Vector2(165, 350), "Group Button #5", Color.White, Color.Black)}));
            //((ButtonGroup)formCollection["form1"]["buttongroup1"]).OnChangeSelection = ButtonGroup1_ChangeSelection;

            ////Add a multiline Textbox
            //formCollection["form1"].Controls.Add(new Textbox("textbox1", new Vector2(310, 50), 130, 80, "This is a test"));
            //((Textbox)formCollection["form1"]["textbox1"]).Scrollbar = Textbox.Scrollbars.Both;

            ////Add a Listbox
            //formCollection["form1"].Controls.Add(new Listbox("listbox1", new Vector2(310, 150), 130, 120,
            //    new string[] { "This is item #1 from the listbox", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9", "Item10" }));
            //((Listbox)formCollection["form1"]["listbox1"]).HorizontalScrollbar = true;

            ////Add a menu to the form
            ////Note: inverted process, first create a submenu then add it when creating the menuItem
            //#region Form1 Menu

            //SubMenu mnuFile = new SubMenu(formCollection["form1"]);
            //mnuFile.Add(new MenuItem("mnuFileClose", "&Close", Form1_mnuFileClose), null);
            //mnuFile.Add(new MenuItem("", "-", Form1_mnuFileClose), null);
            //mnuFile.Add(new MenuItem("mnuFileExit", "E&xit", Form1_mnuFileExit), null);

            //SubMenu mnuView = new SubMenu(formCollection["form1"]);
            //mnuView.Add(new MenuItem("mnuViewToggleFS", "&Toggle Fullscreen", Form1_mnuViewToggleFS), null);

            //SubMenu mnuTestSubMenu0 = new SubMenu(formCollection["form1"]);
            //mnuTestSubMenu0.Add(new MenuItem("mnuTestSubItem0", "SubMenuItem0", null), null);
            //mnuTestSubMenu0.Add(new MenuItem("mnuTestSubItem1", "SubMenuItem1", null), null);

            //SubMenu mnuTestSubMenu1 = new SubMenu(formCollection["form1"]);
            //mnuTestSubMenu1.Add(new MenuItem("mnuTestSubItem0", "SubMenuItem0", null), null);
            //mnuTestSubMenu1.Add(new MenuItem("mnuTestSubItem1", "SubMenuItem1", null), null);

            //SubMenu mnuTest = new SubMenu(formCollection["form1"]);
            //mnuTest.Add(new MenuItem("mnuTestItem0", "MenuItem0", null), mnuTestSubMenu0);
            //mnuTest.Add(new MenuItem("mnuTestItem0", "MenuItem1", null), mnuTestSubMenu1);
            //mnuTest.Add(new MenuItem("mnuTestItem0", "MenuItem2", null), null);

            //formCollection["form1"].Menu = new Menu("form1Menu");
            //formCollection["form1"].Menu.Add(new MenuItem("mnuFile", "&File", null), mnuFile);
            //formCollection["form1"].Menu.Add(new MenuItem("mnuView", "&View", null), mnuView);
            //formCollection["form1"].Menu.Add(new MenuItem("mnuView", "&Test", null), mnuTest);

            //#endregion

            ////Add a ProgressBar
            //formCollection["form1"].Controls.Add(new Progressbar("progressbar1", new Vector2(15, 295), 125, 15, true));

            ////Add a Potentiometer
            //formCollection["form1"].Controls.Add(new Potentiometer("potentiometer1", new Vector2(120, 135)));
            //((Potentiometer)formCollection["form1"]["potentiometer1"]).OnChangeValue = Potentiometer_OnChangeValue;

            //formCollection["form1"].Controls.Add(new ComboBox("combo1", new Vector2(450, 50), 120, new string[] { "Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8" }));
            //formCollection["form1"]["combo1"].FontName = "pescadero9b";

            //formCollection["form1"].Controls.Add(new Button("btAdd", new Vector2(440, 100), "Add to Listbox", Color.White, Color.Black));
            //formCollection["form1"]["btAdd"].OnPress = Button1_OnPress;

            //Show the form

            formCollection["form1"].Show();

            #endregion

            //white corner bug for some reason if not focused.. NEED TO FIX
            formCollection["form1"].Focus();
            formCollection["form1"].Hide();
            formCollection["form1"].Minimize();
            formCollection["form1"].MinimizeButton.IsGrayedOut = false;
            formCollection["form1"].CloseButton.IsGrayedOut = true;
            formCollection["form1"].MinimizeButton.OnRelease = HideForm1;
            new MessageBox(new Vector2(250, 200), "Controls", string.Format("Hello {0}!\n\nCurrent controls:\n\nWalking: arrow keys\nShoot: Left mouse button\nChange weapon: Scrollwheel\nCircle of healing: m\nSlowmotion: Right shift", Player.Name), MessageBox.Type.MB_OK);

            LoadXpBar();
            LoadhealthBar();
            LoadWeaponBar();
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            aCurrentKeyboardState = Keyboard.GetState();
            aCurrentMouseState = Mouse.GetState();

            audioEngine.Update();

            foreach (var u in UnitsInGame)
            {
                if (u.IsDead)
                    u.Revive();

                Matrix tranform =
                        Matrix.CreateTranslation(new Vector3(-new Vector2(Enemy.Size.Width / 2, Enemy.Size.Height / 2), 0.0f)) *
                        Matrix.CreateRotationZ(Enemy.Rotation) *
                        Matrix.CreateTranslation(new Vector3(Enemy.Position, 0.0f));

                //Player Bounding rectangle
                PlayerRectangle = new Rectangle((int)Player.Position.X - ((int)Player.Size.Width / 2), (int)Player.Position.Y - ((int)Player.Size.Height / 2), Player.mSpriteTexture.Width, Player.mSpriteTexture.Height);
                Unit hittingOwner = null;
                var hit = bullet.UpdateBullets(u, u.CollisionBox, u.TextureData, tranform, ScreenWidth, ScreenHeight, soundBank, this.Content, out hittingOwner);

                Player shooter = (Player)hittingOwner;

                 if (hit && (shooter != null) && (shooter != u))
                 {
                     u.TookBullet(shooter.weapon.Damage, shooter);
                 }

            }

            if (aCurrentKeyboardState.IsKeyDown(Keys.F8))
            {
                graphics.ToggleFullScreen();
            }

            //Save Requests
            if (aCurrentKeyboardState.IsKeyDown(Keys.Y) && !SaveRequested)
            {
                SaveRequested = true;
                storage_result = Guide.BeginShowStorageDeviceSelector(PlayerIndex.One,
                    null, null);
            }

            if (aCurrentKeyboardState.IsKeyDown(Keys.U) && !LoadRequested)
            {
                LoadRequested = true;
                storage_result = Guide.BeginShowStorageDeviceSelector(PlayerIndex.One, null, null);
            }

            if (SaveRequested && storage_result.IsCompleted)
            {

                StorageDevice device = Guide.EndShowStorageDeviceSelector(storage_result);
                if (device != null && device.IsConnected)
                {
                    Player.Save(device);
                }
                // Reset the request flag
                SaveRequested = false;
            }
            else if (LoadRequested && storage_result.IsCompleted)
            {
                StorageDevice device = Guide.EndShowStorageDeviceSelector(storage_result);
                if (device != null && device.IsConnected)
                {
                Player.Load(device);
                }
                if (device != null && device.IsConnected)
                {
                    Player.Load(device);
                }
                // Reset the request flag
                SaveRequested = false;
            }

            //Scroll-wheel movement for weapon switching
            if (aCurrentMouseState.ScrollWheelValue > OldScrollWheelValue)
            {
                Player.NextWeapon();
               // bullet.Texture = this.Content.Load<Texture2D>(mPlayerSprite.GetBulletTexture());
                OldScrollWheelValue = aCurrentMouseState.ScrollWheelValue;
            }

            if (aCurrentMouseState.ScrollWheelValue < OldScrollWheelValue)
            {
                Player.PreviousWeapon();
                //bullet.Texture = this.Content.Load<Texture2D>(mPlayerSprite.GetBulletTexture());
                OldScrollWheelValue = aCurrentMouseState.ScrollWheelValue;

            }

            if (aCurrentMouseState.LeftButton == ButtonState.Pressed && mPreviousMouseState.LeftButton == ButtonState.Pressed && InMenu == false)
            {
                Player.Shoot(bullet, soundBank);
            }

            //Update the form collection
            formCollection.Update(gameTime);

            // Allows the game to exit
            if (aCurrentKeyboardState.IsKeyDown(Keys.Escape) == true)
            {
                //this.Exit();
                if (formCollection["form1"].State == Form.WindowState.Minimized)
                {
                    formCollection["form1"].Visible = true;
                    formCollection["form1"].Show();
                }
            }

            if (formCollection["form1"].State != Form.WindowState.Minimized)
            {
                InMenu = true;
                FormCollection.IsCursorVisible = true;
            }
            else
            {
                InMenu = false;
                FormCollection.IsCursorVisible = false;
            }

            //Slomotion button
            if (aCurrentKeyboardState.IsKeyDown(Keys.RightShift))
                gameTime = new GameTime(gameTime.TotalRealTime, gameTime.ElapsedRealTime, new TimeSpan((long)(gameTime.TotalGameTime.Ticks * 0.33f)), new TimeSpan((long)(gameTime.ElapsedGameTime.Ticks * 0.33f)));

            //Activate Circle of healing
            if (aCurrentKeyboardState.IsKeyDown(Keys.M))
                talents_medic.Talent_active = true;
            else
                talents_medic.Talent_active = false;

            time = (float)gameTime.ElapsedGameTime.TotalSeconds;

            // TODO: Add your update logic here
            if (InMenu == false)
                Player.Update(gameTime, this.Content);

            UpdateWeaponBar();

            #region Shadow & lighting update
            lights[0].Position = Player.Position;
            rotatedlights[0].Position = Player.Position;
            rotatedlights[0].Rotation = Player.Rotation;
            #endregion

            #region Network update

            if (_client != null || _server != null)
            {
                UpdateNetwork();
            }
            else
            {
                //We get the state of the keyboard at this moment which will hold keys pressed ect.
                //if the H key is pressed we call the HostClicked Routine.
                if (aCurrentKeyboardState.IsKeyDown(Keys.H))
                {
                    HostClicked();
                }
                //If the C key is pressed we call the ClientClicked Routine
                if (aCurrentKeyboardState.IsKeyDown(Keys.C))
                {
                    ClientClicked();
                }
            }

            #endregion

            mPreviousKeyboardState = aCurrentKeyboardState;
            mPreviousMouseState = aCurrentMouseState;

            base.Update(gameTime);
        }

        /// <summary>
        /// Builds the list of ConvexHulls that we are going o use
        /// </summary>
        private void BuildObjectList()
        {
            ConvexHull.InitializeStaticMembers(GraphicsDevice);
            objects = new ConvexHull[37];
            Color wallColor = Color.Black;

            Vector2[] points = new Vector2[4];
            points[0] = new Vector2(0, 0);
            points[1] = new Vector2(0, 20);
            points[2] = new Vector2(800, 20);
            points[3] = new Vector2(800, 0);

            objects[0] = new ConvexHull(this, points, wallColor, Vector2.Zero);
            objects[1] = new ConvexHull(this, points, wallColor, new Vector2(0, 580));

            points[0] = new Vector2(0, 20);
            points[1] = new Vector2(0, 580);
            points[2] = new Vector2(20, 580);
            points[3] = new Vector2(20, 20);

            objects[2] = new ConvexHull(this, points, wallColor, Vector2.Zero);
            objects[3] = new ConvexHull(this, points, wallColor, new Vector2(780, 0));

            points[0] = new Vector2(0, 0);
            points[1] = new Vector2(0, 20);
            points[2] = new Vector2(560, 20);
            points[3] = new Vector2(560, 0);

            objects[4] = new ConvexHull(this, points, wallColor, new Vector2(20, 140));
            objects[5] = new ConvexHull(this, points, wallColor, new Vector2(20, 440));

            points[0] = new Vector2(0, 0);
            points[1] = new Vector2(0, 140);
            points[2] = new Vector2(20, 140);
            points[3] = new Vector2(20, 0);

            objects[6] = new ConvexHull(this, points, wallColor, new Vector2(580, 140));
            objects[7] = new ConvexHull(this, points, wallColor, new Vector2(580, 320));

            points[0] = new Vector2(0, 0);
            points[1] = new Vector2(0, 20);
            points[2] = new Vector2(20, 20);
            points[3] = new Vector2(20, 0);

            objects[8] = new ConvexHull(this, points, wallColor, new Vector2(640, 140));
            objects[9] = new ConvexHull(this, points, wallColor, new Vector2(640, 240));
            objects[10] = new ConvexHull(this, points, wallColor, new Vector2(640, 340));
            objects[11] = new ConvexHull(this, points, wallColor, new Vector2(640, 440));

            objects[12] = new ConvexHull(this, points, wallColor, new Vector2(720, 140));
            objects[13] = new ConvexHull(this, points, wallColor, new Vector2(720, 240));
            objects[14] = new ConvexHull(this, points, wallColor, new Vector2(720, 340));
            objects[15] = new ConvexHull(this, points, wallColor, new Vector2(720, 440));

            points[0] = new Vector2(0, 0);
            points[1] = new Vector2(0, 80);
            points[2] = new Vector2(20, 80);
            points[3] = new Vector2(20, 0);

            objects[16] = new ConvexHull(this, points, wallColor, new Vector2(100, 500));

            objects[17] = new ConvexHull(this, points, wallColor, new Vector2(200, 460));

            objects[18] = new ConvexHull(this, points, wallColor, new Vector2(300, 500));
            objects[19] = new ConvexHull(this, points, wallColor, new Vector2(400, 460));

            objects[20] = new ConvexHull(this, points, wallColor, new Vector2(500, 500));
            objects[21] = new ConvexHull(this, points, wallColor, new Vector2(580, 460));

            points[0] = new Vector2(0, 0);
            points[1] = new Vector2(0, 40);
            points[2] = new Vector2(60, 40);
            points[3] = new Vector2(60, 0);

            objects[22] = new ConvexHull(this, points, wallColor, new Vector2(160, 280));
            objects[23] = new ConvexHull(this, points, wallColor, new Vector2(360, 280));

            points[0] = new Vector2(0, -20);
            points[1] = new Vector2(-20, 0);
            points[2] = new Vector2(0, 20);
            points[3] = new Vector2(20, 0);

            objects[24] = new ConvexHull(this, points, wallColor, new Vector2(460, 80));
            objects[25] = new ConvexHull(this, points, wallColor, new Vector2(560, 80));
            objects[26] = new ConvexHull(this, points, wallColor, new Vector2(160, 80));

            points = new Vector2[8];
            float angleSlice = MathHelper.TwoPi / 8.0f;

            for (int i = 0; i < 8; i++)
            {
                points[i] = new Vector2((float)Math.Sin(angleSlice * i), (float)Math.Cos(angleSlice * i)) * 20;
            }

            objects[27] = new ConvexHull(this, points, wallColor, new Vector2(140, 220));
            objects[28] = new ConvexHull(this, points, wallColor, new Vector2(240, 220));
            objects[29] = new ConvexHull(this, points, wallColor, new Vector2(340, 220));
            objects[30] = new ConvexHull(this, points, wallColor, new Vector2(440, 220));

            objects[31] = new ConvexHull(this, points, wallColor, new Vector2(140, 380));
            objects[32] = new ConvexHull(this, points, wallColor, new Vector2(240, 380));
            objects[33] = new ConvexHull(this, points, wallColor, new Vector2(340, 380));
            objects[34] = new ConvexHull(this, points, wallColor, new Vector2(440, 380));

            objects[35] = new ConvexHull(this, points, wallColor, new Vector2(80, 300));
            objects[36] = new ConvexHull(this, points, wallColor, new Vector2(500, 300));
        }

        /// <summary>
        /// Clears the alpha channel
        /// </summary>
        private void ClearAlphaToOne()
        {
            GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.Alpha;
            spriteBatch.Begin(SpriteBlendMode.None);
            spriteBatch.Draw(alphaClearTexture, new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White);
            spriteBatch.End();
            GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.All;
        }

        /// <summary>
        /// Draws the groundtextures, This is the first batch that is rendered to the screen
        /// </summary>
        private void DrawGround()
        {
            //draw the tile texture tiles across the screen
            Rectangle source = new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
            spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);

            GraphicsDevice.SamplerStates[0].AddressU = TextureAddressMode.Wrap;
            GraphicsDevice.SamplerStates[0].AddressV = TextureAddressMode.Wrap;

            spriteBatch.Draw(this.Content.Load<Texture2D>("tile_sand"), Vector2.Zero, source, Color.White, 0, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);

            spriteBatch.End();
        }

        /// <summary>
        /// Draws the lightmap to the lightmap render target
        /// </summary>
        private void DrawLightmap()
        {
            GraphicsDevice.SetRenderTarget(0, lightMap);

            //clear to some small ambient light
            GraphicsDevice.Clear(new Color(35, 35, 35));

            foreach (LightSource light in lights)
            {
                //clear alpha to 1
                ClearAlphaToOne();

                //draw all shadows
                //write only to the alpha channel, which sets alpha to 0
                GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.Alpha;
                GraphicsDevice.RenderState.CullMode = CullMode.None;
                GraphicsDevice.RenderState.AlphaBlendEnable = true;
                GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;
                GraphicsDevice.RenderState.SourceBlend = Blend.One;

                foreach (ConvexHull ch in objects)
                {
                    //draw shadow
                    ch.DrawShadows(light);
                }
                GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.All;

                //draw the light shape
                //where Alpha is 0, nothing will be written
                spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
                GraphicsDevice.RenderState.DestinationBlend = Blend.One;
                GraphicsDevice.RenderState.SourceBlend = Blend.DestinationAlpha;
                GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;
                GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = true;
                light.Draw(spriteBatch);
                spriteBatch.End();
            }

            foreach (LightSource light in rotatedlights)
            {
                //clear alpha to 1
                ClearAlphaToOne();

                //draw all shadows
                //write only to the alpha channel, which sets alpha to 0
                GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.Alpha;
                GraphicsDevice.RenderState.CullMode = CullMode.None;
                GraphicsDevice.RenderState.AlphaBlendEnable = true;
                GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;
                GraphicsDevice.RenderState.SourceBlend = Blend.One;

                foreach (ConvexHull ch in objects)
                {
                    //draw shadow
                    ch.DrawShadows(light);
                }
                GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.All;

                //draw the light shape
                //where Alpha is 0, nothing will be written
                spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.SaveState);
                GraphicsDevice.RenderState.DestinationBlend = Blend.One;
                GraphicsDevice.RenderState.SourceBlend = Blend.DestinationAlpha;
                GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;
                GraphicsDevice.RenderState.SeparateAlphaBlendEnabled = true;
                light.DrawRotated(spriteBatch);
                spriteBatch.End();
            }
                //clear alpha, to avoid messing stuff up later
                ClearAlphaToOne();
                GraphicsDevice.SetRenderTarget(0, null);
        }

        #endregion Methods

        #region Other

        ///// <summary>
        ///// Menu screen provides options to create or join network sessions.
        ///// </summary>
        //void UpdateMenuScreen()
        //{
        //    if (IsActive)
        //    {
        //        if (Gamer.SignedInGamers.Count == 0)
        //        {
        //            // If there are no profiles signed in, we cannot proceed.
        //            // Show the Guide so the user can sign in.
        //            Guide.ShowSignIn(maxLocalGamers, true);
        //        }
        //        else if (aCurrentKeyboardState.IsKeyDown(Keys.F1))
        //        {
        //            // Create a new session?
        //            CreateSession();
        //        }
        //        else if (aCurrentKeyboardState.IsKeyDown(Keys.F2))
        //        {
        //            // Join an existing session?
        //            JoinSession();
        //        }
        //    }
        //}
        ///// <summary>
        ///// Starts hosting a new network session.
        ///// </summary>
        //void CreateSession()
        //{
        //    try
        //    {
        //        networkSession = NetworkSession.Create(NetworkSessionType.PlayerMatch, maxLocalGamers, maxGamers);
        //        new MessageBox(new Vector2(250, 100), "Session created!", "Session created!", MessageBox.Type.MB_OK).Show();
        //        HookSessionEvents();
        //    }
        //    catch (Exception e)
        //    {
        //        new MessageBox(new Vector2(250, 100), "Error", e.Message, MessageBox.Type.MB_OK).Show();
        //    }
        //}
        ///// <summary>
        ///// Joins an existing network session.
        ///// </summary>
        //void JoinSession()
        //{
        //    try
        //    {
        //        // Search for sessions.
        //        using (AvailableNetworkSessionCollection availableSessions = NetworkSession.Find(NetworkSessionType.PlayerMatch, maxLocalGamers, null))
        //        {
        //            if (availableSessions.Count == 0)
        //            {
        //                MessageBox NoSession = new MessageBox(new Vector2(250, 100), "No network session found.", "No network session found", MessageBox.Type.MB_OK);
        //                NoSession.Show();
        //                return;
        //            }
        //            // Join the first session we found.
        //            networkSession = NetworkSession.Join(availableSessions[0]);
        //            HookSessionEvents();
        //        }
        //    }
        //    catch (Exception e)
        //    {
        //        new MessageBox(new Vector2(250, 100), "Error", e.Message, MessageBox.Type.MB_OK).Show();
        //    }
        //}
        ///// <summary>
        ///// After creating or joining a network session, we must subscribe to
        ///// some events so we will be notified when the session changes state.
        ///// </summary>
        //void HookSessionEvents()
        //{
        //    networkSession.GamerJoined += GamerJoinedEventHandler;
        //    networkSession.SessionEnded += SessionEndedEventHandler;
        //}
        ///// <summary>
        ///// This event handler will be called whenever a new gamer joins the session.
        ///// We use it to allocate a Tank object, and associate it with the new gamer.
        ///// </summary>
        //void GamerJoinedEventHandler(object sender, GamerJoinedEventArgs e)
        //{
        //    int gamerIndex = networkSession.AllGamers.IndexOf(e.Gamer);
        //    e.Gamer.Tag = new Player();
        //}
        ///// <summary>
        ///// Event handler notifies us when the network session has ended.
        ///// </summary>
        //void SessionEndedEventHandler(object sender, NetworkSessionEndedEventArgs e)
        //{
        //    new MessageBox(new Vector2(100, 100), "Session ended", e.EndReason.ToString(), MessageBox.Type.MB_OK);
        //    networkSession.Dispose();
        //    networkSession = null;
        //}
        ///// <summary>
        ///// Updates the state of the network session, moving the tanks
        ///// around and synchronizing their state over the network.
        ///// </summary>
        //void UpdateNetworkSession(GameTime TheGameTime)
        //{
        //    // Update our locally controlled tanks, and send their
        //    // latest position data to everyone in the session.
        //    foreach (LocalNetworkGamer gamer in networkSession.LocalGamers)
        //    {
        //        UpdateLocalGamer(gamer, TheGameTime);
        //    }
        //    // Pump the underlying session object.
        //    networkSession.Update();
        //    // Make sure the session has not ended.
        //    if (networkSession == null)
        //        return;
        //    // Read any packets telling us the positions of remotely controlled tanks.
        //    foreach (LocalNetworkGamer gamer in networkSession.LocalGamers)
        //    {
        //        ReadIncomingPackets(gamer);
        //    }
        //}
        ///// <summary>
        ///// Helper for updating a locally controlled gamer.
        ///// </summary>
        //void UpdateLocalGamer(LocalNetworkGamer gamer, GameTime TheGameTime)
        //{
        //    // Look up what tank is associated with this local player.
        //    Player localPlayer = gamer.Tag as Player;
        //    // Update the tank.
        //    mPlayerSprite.UpdateMovement(aCurrentKeyboardState);
        //    localPlayer.Update(TheGameTime, this.Content);
        //    // Write the tank state into a network packet.
        //    packetWriter.Write(localPlayer.Position);
        //    packetWriter.Write(localPlayer.Rotation);
        //    //packetWriter.Write(localTank.TurretRotation);
        //    // Send the data to everyone in the session.
        //    gamer.SendData(packetWriter, SendDataOptions.InOrder);
        //}
        ///// <summary>
        ///// Helper for reading incoming network packets.
        ///// </summary>
        //void ReadIncomingPackets(LocalNetworkGamer gamer)
        //{
        //    // Keep reading as long as incoming packets are available.
        //    while (gamer.IsDataAvailable)
        //    {
        //        NetworkGamer sender;
        //        // Read a single packet from the network.
        //        gamer.ReceiveData(packetReader, out sender);
        //        // Discard packets sent by local gamers: we already know their state!
        //        if (sender.IsLocal)
        //            continue;
        //        // Look up the tank associated with whoever sent this packet.
        //        Player remotePlayer = sender.Tag as Player;
        //        // Read the state of this tank from the network packet.
        //        remotePlayer.Position = packetReader.ReadVector2();
        //        remotePlayer.Rotation = packetReader.ReadSingle();
        //        //remotePlayer.TurretRotation = packetReader.ReadSingle();
        //    }
        //}

        #endregion Other
    }
}